package com.quad.innovators.salesease.service.impl.base;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quad.innovators.salesease.common.result.PageResultBean;
import com.quad.innovators.salesease.common.utils.SystemCodeUtils;
import com.quad.innovators.salesease.converter.WarehouseConverter;
import com.quad.innovators.salesease.enums.ResultCode;
import com.quad.innovators.salesease.enums.StatusEnum;
import com.quad.innovators.salesease.enums.SystemCodeEnum;
import com.quad.innovators.salesease.exception.BusinessException;
import com.quad.innovators.salesease.mapper.base.WarehouseMapper;
import com.quad.innovators.salesease.model.common.Option;
import com.quad.innovators.salesease.model.entity.base.BrandProvider;
import com.quad.innovators.salesease.model.entity.base.Warehouse;
import com.quad.innovators.salesease.model.form.base.WarehouseForm;
import com.quad.innovators.salesease.model.query.base.WarehousePageQuery;
import com.quad.innovators.salesease.model.vo.base.WarehouseVO;
import com.quad.innovators.salesease.service.base.WarehouseService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, Warehouse> implements WarehouseService {

    private final WarehouseConverter warehouseConverter;

    @Override
    public PageResultBean<WarehouseVO> listPaged(WarehousePageQuery queryParams) {
        Page<WarehouseVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        Page<WarehouseVO> warehouseVOPage = this.baseMapper.listPaged(page, queryParams);
        return warehouseConverter.toPageVo(warehouseVOPage);
    }

    @Override
    public boolean save(WarehouseForm form) {
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<Warehouse>()
                .eq(Warehouse::getName, form.getName())
        );
        if(count > 0){
            throw BusinessException.resultCode(ResultCode.ALREADY_EXISTS_ERROR);
        }
        Warehouse entity = warehouseConverter.toEntity(form);
        entity.setCode(SystemCodeUtils.getCode(SystemCodeEnum.WAREHOUSE));
        this.baseMapper.insert(entity);
        return true;
    }

    @Override
    public WarehouseForm getFormData(String code) {
        Warehouse warehouse = this.baseMapper.selectByCode(code);
        if(warehouse==null) {
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        return warehouseConverter.toForm(warehouse);
    }

    @Override
    public boolean update(String code, WarehouseForm form) {
        Warehouse formData = this.baseMapper.selectByCode(code);
        if(formData == null){
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        // 是否已经存在
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<Warehouse>()
                .eq(Warehouse::getName, form.getName())
                .ne(Warehouse::getCode, code)
        );
        if(count > 0){
            throw BusinessException.resultCode(ResultCode.ALREADY_EXISTS_ERROR);
        }
        Warehouse entity = warehouseConverter.toEntity(form);
        entity.setId(formData.getId());
        this.baseMapper.updateById(entity);
        return true;
    }

    @Override
    public boolean updateStatus(String code, Integer status) {
        Warehouse formData = this.baseMapper.selectByCode(code);
        if(formData == null){
            throw BusinessException.resultCode(ResultCode.NOT_FOUND);
        }
        formData.setStatus(status);
        this.baseMapper.updateById(formData);
        return true;
    }

    @Override
    public List<Option<String>> listOptions() {
        List<Warehouse> warehouseList = this.baseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getStatus, StatusEnum.ENABLE.getValue()));
        return warehouseList.stream().map(it -> new Option<>(it.getCode(), it.getName())).collect(Collectors.toList());
    }
}
